home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / GX Libraries / StorageLibrary.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-02  |  7.3 KB  |  266 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3.     File:        StorageLibrary.c
  4.  
  5.     Contains:    graphics libraries - primitive flattening library routines
  6.     
  7.     Written by:    Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  8.     
  9.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <2>      5/1/95    jtd        bringing in final 1.1 source changes
  14.          <1>      1/9/95    JD        First checked in.
  15. */
  16.  
  17. #include <Memory.h>
  18. #include <Errors.h>
  19. #include <Files.h>
  20. #include <MixedMode.h>
  21.  
  22. #include <GXFonts.h>
  23. #include "GraphicsLibraries.h"
  24. #include "ScalerTypes.h"
  25. #include "StorageLibrary.h"
  26. /*
  27.    The following routine is an example of how to write a spooling procedure to
  28.    work with GXFlattenShape and GXUnflattenShape.  For writing, it stores the data in
  29.    a Handle which must be disposed of after the GXFlattenShape call.  When reading,
  30.    it expects the 'data' field of the gxSpoolBlock to have a handle to the data to be
  31.    unflattened.
  32. */
  33.  
  34. #define allocationIncrement   1024     /* the storage handle is grown by this amount */
  35.  
  36. /* jtdfix - wrap C linkage statements around everything since this is public source */
  37.  
  38. #ifdef __cplusplus
  39. extern "C" {
  40. #endif
  41.  
  42. static long HandleSpoolProc(gxSpoolCommand command,  userSpool *block)
  43. {
  44.    switch (command)
  45.    {
  46.       case gxOpenReadSpool:
  47.          block->size = 0;
  48.          block->position = 0;
  49.       break;
  50.       case gxOpenWriteSpool:
  51.          block->data = NewHandle(allocationIncrement);
  52.          block->size = allocationIncrement;
  53.          block->position = 0;
  54.       break;
  55.       
  56.       case gxReadSpool:
  57.          BlockMove((*(char **) block->data) + block->position, block->spool.buffer, block->spool.count);
  58.          block->position += block->spool.count;
  59.       break;
  60.  
  61.       case gxWriteSpool:
  62.       {  register long oldPosition;
  63.  
  64.          oldPosition = block->position;
  65.          block->position += block->spool.count;
  66.  
  67.          /* make sure there is at least enough room for one buffer size past current pointer */
  68.          if (block->position + block->spool.bufferSize > block->size)      
  69.          {
  70.             block->size += block->spool.bufferSize;
  71.             HUnlock((Handle) block->data);
  72.             SetHandleSize((Handle) block->data, block->size);
  73.             HLock((Handle) block->data);
  74.          }
  75.          BlockMove(block->spool.buffer, (*(char **) block->data + oldPosition), block->spool.count);
  76.       }
  77.       break;
  78.       
  79.       case gxCloseSpool:
  80.          SetHandleSize((Handle) block->data, block->position);
  81.       break;
  82.    }
  83.    return 0;
  84. }
  85.  
  86. #ifdef __cplusplus
  87. }
  88. #endif
  89.  
  90. /*
  91.    This routine spools to and from a file.  The file must have previously been created and opened,
  92.    and its refNum is expected to be in the refnum field of the block.
  93. */
  94. static long FileSpoolProc(gxSpoolCommand command, userSpool *block)
  95. {
  96.    short err;
  97.    
  98.    switch (command) {
  99.       case gxOpenReadSpool:
  100.       break;
  101.       case gxOpenWriteSpool:
  102.       break;
  103.       case gxReadSpool:
  104.       {
  105.          long count = block->spool.count;
  106.          err = FSRead(block->reference, &count, block->spool.buffer);
  107.          IfDebug(err && err != eofErr, "\pFSRead failed");
  108.       } break;
  109.       case gxWriteSpool:
  110.       {
  111.          long count = block->spool.count;
  112.          err = FSWrite(block->reference, &count, block->spool.buffer);
  113.          IfDebug(err, "\pFSWrite failed");
  114.       } break;
  115.       case gxCloseSpool:
  116.       break;
  117.       default:
  118.          IfDebug(true, "\punexpected spool command");
  119.    }
  120.    return 0;
  121. }
  122.  
  123. Handle ShapeToHandle(gxShape source)
  124. {
  125.     return ShapeToHandleWithFlags(source, gxFontListFlatten | gxFontGlyphsFlatten);
  126. }
  127.  
  128. Handle ShapeToHandleWithFlags(gxShape source, gxFlattenFlag flags)
  129. {
  130.    userSpool block;
  131.    
  132.    NilShapeReturnNil(source);
  133.    block.spool.spoolProcedure = NewgxSpoolProc(HandleSpoolProc);
  134.    block.spool.buffer = nil;
  135.    block.spool.bufferSize = 0;
  136.    GXFlattenShape(source, flags, &block.spool);
  137.    DisposeRoutineDescriptor(block.spool.spoolProcedure);
  138.    return (Handle) block.data;
  139. }
  140.  
  141. gxShape HandleToShape(Handle source, long count, const gxViewPort portList[])
  142. {
  143.    userSpool block;
  144.    gxShape dest;
  145.    
  146.    block.spool.spoolProcedure = NewgxSpoolProc(HandleSpoolProc);
  147.    block.spool.buffer = nil;
  148.    block.spool.bufferSize = 0;
  149.    block.data = source;
  150.    dest = GXUnflattenShape(&block.spool, count, portList);
  151.    DisposeRoutineDescriptor(block.spool.spoolProcedure);
  152.    return dest;
  153. }
  154.  
  155. void ShapeToFRef(gxShape source, short refNum)
  156. {
  157.     userSpool block;
  158.  
  159.     NilShapeReturn(source);
  160.     block.spool.spoolProcedure = NewgxSpoolProc(FileSpoolProc);
  161.     block.reference = refNum;
  162.     block.spool.buffer = nil;
  163.     block.spool.bufferSize = 0;
  164.     GXFlattenShape(source,  gxFontListFlatten | gxFontGlyphsFlatten, &block.spool);
  165.     DisposeRoutineDescriptor(block.spool.spoolProcedure);
  166. }
  167.  
  168. gxShape FRefToShape(short refNum, long count, const gxViewPort portList[])
  169. {
  170.     userSpool block;
  171.     gxShape dest;
  172.     
  173.     block.spool.spoolProcedure = NewgxSpoolProc(FileSpoolProc);
  174.     block.reference = refNum;
  175.     block.spool.buffer = nil;
  176.     block.spool.bufferSize = 0;
  177.     dest = GXUnflattenShape(&block.spool, count, portList);
  178.     DisposeRoutineDescriptor(block.spool.spoolProcedure);
  179.     return dest;
  180. }
  181.  
  182. void ShapeToFile(gxShape source, Str255 fileName, short vRefNum, OSType creator, OSType fileType)
  183. {
  184.     short refNum;
  185.     short err;
  186.     
  187.     NilShapeReturn(source);
  188.     NilParamReturn(fileName);
  189.     
  190.     if (creator == 0) creator = 'sLib';
  191.     if (fileType == 0) fileType = 'flat';
  192.     err = Create(fileName, vRefNum, creator, fileType);
  193.     if (err == dupFNErr) {
  194.         FSDelete(fileName, vRefNum);
  195.         err = Create(fileName, vRefNum, creator, fileType);
  196.     }
  197.     IfDebug(err, "\pCreate failed");
  198.     err = FSOpen(fileName, vRefNum, &refNum);
  199.     IfDebug(err, "\pFSOpen failed");
  200.     ShapeToFRef(source, refNum);
  201.     err = FSClose(refNum);
  202.     IfDebug(err, "\pFSClose failed");
  203. }
  204.  
  205. gxShape FileToShape(Str255 fileName, short vRefNum, long count, const gxViewPort portList[])
  206. {
  207.     short refNum;
  208.     short err;
  209.     gxShape dest;
  210.     
  211.     err = FSOpen(fileName, vRefNum, &refNum);
  212.     IfDebug(err, "\pFSOpen failed");
  213.     dest = FRefToShape(refNum, count, portList);
  214.     err = FSClose(refNum);
  215.     IfDebug(err, "\pFSClose failed");
  216.     return dest;
  217. }
  218.  
  219. gxShape FSSpecToShape(FSSpec* spec, long count, const gxViewPort portList[]);
  220. gxShape FSSpecToShape(FSSpec* spec, long count, const gxViewPort portList[])
  221. {
  222.     short refNum;
  223.     short err;
  224.     gxShape dest;
  225.     
  226.     err = FSpOpenDF(spec, fsCurPerm, &refNum);
  227.     dest = FRefToShape(refNum, count, portList);
  228.     err = FSClose(refNum);
  229.     IfDebug(err, "\pFSClose failed");
  230.     return dest;
  231. }
  232.  
  233. Handle FontToHandle(gxFont fontID, long glyphBits[])
  234. {
  235.    userSpool block;
  236.    scalerStream stream;
  237.    
  238.    block.spool.spoolProcedure = NewgxSpoolProc(HandleSpoolProc);
  239.    block.spool.buffer = nil;
  240.    block.spool.bufferSize = 0;
  241.  
  242.    stream.streamRefCon = fontID;
  243.    stream.types = type1StreamType;        // flattenedStreamType;
  244.    stream.action = downloadStreamAction;
  245.    stream.memorySize = 0;
  246.    stream.variationCount = selectAllVariations;
  247.    stream.variations = nil;
  248.    stream.info.font.encoding = 0;
  249.    stream.info.font.glyphBits = glyphBits;
  250.    stream.info.font.name = (char*)"\pSkia-ps";
  251.  
  252.    GXFlattenFont(fontID, &stream, &block.spool);
  253.    DisposeRoutineDescriptor(block.spool.spoolProcedure);
  254.    return (Handle) block.data;
  255. }
  256.  
  257. gxFont HandleToFont(Handle source)
  258. {
  259.    /*
  260.     * GXNewFont does not copy the data in source, so you can't dispose
  261.     * of it until you have called GXDisposeFont().
  262.    */
  263.    return GXNewFont(gxHandleFontStorage, source, 0);
  264. }
  265.  
  266.